﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Linq.Expressions;
using System.Reflection;

namespace blackhouse.WebNemo.Business.Groups {
    public class GroupRecords : IEnumerable<GroupRecord> {

        #region Fields

        private IGroup group;
        private Factory factory = Factory.Instance();
        private IGroupRecord[] records;
        private CultureInfo recordCulture;

        #endregion

        #region Constructors

        public GroupRecords(int groupId)
            : this(groupId, CultureInfo.CurrentCulture) { }

        public GroupRecords(string groupName)
            : this(groupName, CultureInfo.CurrentCulture) {
        }

        public GroupRecords(IGroup group)
            : this(group, CultureInfo.CurrentCulture) {
        }

        public GroupRecords(int groupId, CultureInfo language) {
            this.group = factory.GetGroup(groupId);
            this.recordCulture = language;
        }

        public GroupRecords(string groupName, CultureInfo language) {
            this.group = factory.GetGroup(groupName);
            this.recordCulture = language;
        }

        public GroupRecords(IGroup group, CultureInfo language) {
            this.group = group;
            this.recordCulture = language;
        }

        #endregion

        #region Methods

        private IGroupRecord[] GetSourceRecords() {
            if (this.records == null)
                this.records = this.group.GetGroupRecords(this.recordCulture);
            return this.records;
        }

        public GroupRecord[] GetRecords() {
            IGroupRecord[] srecords = this.GetSourceRecords();
            GroupRecord[] records = new GroupRecord[srecords.Length];
            for (int xr = 0; xr < srecords.Length; xr++) {
                records[xr] = new GroupRecord(this.group, srecords[xr], this.recordCulture);
            }
            return records;
        }

        public T[] GetRecords<T>() where T : GroupRecord, new() {
            IGroupRecord[] records = this.GetSourceRecords();
            return this.ConvertRecords<T>(records);

            ////Type t = typeof(T);

            //if (t.GetConstructor(new Type[] { typeof(IGroup), typeof(IGroupRecord) }) != null) {
            //    IGroupRecord[] records = this.group.GetGroupRecords(this.recordCulture);
            //    List<T> tRecords = new List<T>();
            //    foreach (IGroupRecord record in records) {
            //        T tRecord = Activator.CreateInstance(t, this.group, record) as T;
            //        tRecords.Add(tRecord);
            //    }
            //    return tRecords.ToArray();
            //}
            //else
            //    throw new InvalidCastException("Brak konstruktora ctor(IGroup, IGroupRecord)");
        }

        public GroupRecord[] GetRecords(GroupRecordQuery query) {
            return this.group.GetGroupRecords(query, this.recordCulture).Select(gr => new GroupRecord(this.group, gr, recordCulture)).ToArray();
        }

        public T[] GetRecords<T>(GroupRecordQuery query) where T : GroupRecord, new() {
            IGroupRecord[] records = this.group.GetGroupRecords(query, this.recordCulture);
            return this.ConvertRecords<T>(records);
        }

        private T[] ConvertRecords<T>(IGroupRecord[] orginalRecords) where T : GroupRecord, new() {
            RecordConverter<T> converter = new RecordConverter<T>(this.group);
            return converter.ConvertAll(orginalRecords);
        }

        public IEnumerator<GroupRecord> GetEnumerator() {
            return this.GetRecords().OrderByDescending(r => r.LastModifiedTime).GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
            return this.GetRecords().OrderByDescending(r => r.LastModifiedTime).GetEnumerator();
        }

        #endregion

    }
}
